package com.zhang.handler;

import com.zhang.ChannelManage;
import com.zhang.common.codec.MyHttpRequestEncoder;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.util.ReferenceCountUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;

/**
 * 处理用户的请求
 * @author zhanghao
 */
public class HttpReceiveHandler extends ChannelInboundHandlerAdapter {
    /**
     * 日志对象
     */
    static private Logger log = LoggerFactory.getLogger(HttpReceiveHandler.class);
    /**
     * 请求编码
     */
    private MyHttpRequestEncoder httpRequestEncoder = new MyHttpRequestEncoder();

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        log.debug("进到HttpReceiveHandler");
        if(msg instanceof FullHttpRequest){
            log.debug("处理FullHttpRequest消息");
            FullHttpRequest request = (FullHttpRequest) msg;
            //转发http请求
            handle(ctx,request);
        }else{
            ReferenceCountUtil.release(msg);
            log.error("不支持非FullHttpRequest对象");
        }
    }

    /**
     * 转发http 请求到真实服务器
     * @param ctx
     * @param request
     */
    private void handle(ChannelHandlerContext ctx,FullHttpRequest request) throws Exception {
        //获取真实服务器
        Channel realServerChannel = ChannelManage.getRealServerChannel();
        if (null == realServerChannel){
            ReferenceCountUtil.release(request);
            log.error("获取不到真实服务器channel,丢弃数据包");
            return;
        }

        InetSocketAddress sa = (InetSocketAddress) realServerChannel.remoteAddress();
        String host = sa.getHostString();

        int port = sa.getPort();

        log.debug("获取真实主机的host={}和端口={}",host,port);
        if(port == 80){
            request.headers().set(HttpHeaderNames.HOST, host );
        }else{
            request.headers().set(HttpHeaderNames.HOST, host + ":" + port);
        }

        request.setProtocolVersion(HttpVersion.HTTP_1_1);
        request.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);

        List<Object> list = new ArrayList<>();
        httpRequestEncoder.encode(ctx, request, list);
        for (Object o : list) {
            realServerChannel.writeAndFlush(o);
            log.debug("转发http请求至真实服务器:{}:{}", request.method().name(), request.uri());
        }
    }
}
